package 剑指offer;


/**
 * @author: tyy 剑指 Offer
 * 25. K 个一组翻转链表
给你一个链表，每 k 个节点一组进行翻转，请你返回翻转后的链表。

k 是一个正整数，它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍，那么请将最后剩余的节点保持原有顺序。

进阶：

你可以设计一个只使用常数额外空间的算法来解决此问题吗？
你不能只是单纯的改变节点内部的值，而是需要实际进行节点交换。
 * @create: 2021-12-25 17:40
 * @description:
 **/
public class Solution38 {
    public ListNode reverseKGroup1(ListNode head, int k) {
        ListNode pre = null;
        ListNode curr = head;
        int n = k;
        while (n-- >0 && curr.next == null)
        {
            ListNode next = curr.next;
            curr.next = pre;
            pre = curr;
            curr = next;
        }
        System.out.println("pre = " + pre);
        System.out.println("curr = " + curr);
        return head;

    }


    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode tail = head;
        for (int i = 0; i < k; i++) {
            //剩余数量小于k的话，则不需要反转。
            if (tail == null) {
                return head;
            }
            tail = tail.next;
        }
        // 反转前 k 个元素
        ListNode newHead = reverse(head, tail);
        //下一轮的开始的地方就是tail
        head.next = reverseKGroup(tail, k);

        return newHead;
    }

    /*
    左闭又开区间
     */
    private ListNode reverse(ListNode head, ListNode tail) {
        ListNode pre = null;
        ListNode next = null;
        while (head != tail) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;

    }
    public static void main(String[] args) {
        //        4,5,1,9
        ListNode listNode = new ListNode(4);
        listNode.next = new ListNode(5);
        listNode.next.next = new ListNode(1);
        listNode.next.next.next = new ListNode(9);
        ListNode node = new Solution38().reverseKGroup(listNode, 2);
        System.out.println("listNode = " + node);

    }


}
